import { _decorator, Node, Sprite } from 'cc';
import { BaseView } from '../../../../../scripts/libs/rxjs/cc3/BaseView';
import { ReactiveNumber } from '../../../../../scripts/libs/rxjs/cc3/ReactiveNumber';
import { ReactiveBoolean } from '../../../../../scripts/libs/rxjs/cc3/ReactiveBoolean';
import { MergeASAP } from '../../../../../scripts/libs/rxjs/cc3/Merge';
import { ReactiveSet } from '../../../../../scripts/libs/rxjs/cc3/ReactiveSet';
import { SpriteAtlas } from 'cc';
import { UIOpacity } from 'cc';
import { concat, forkJoin, Subscription } from 'rxjs';
import { nullifySubscription } from '../../../../../scripts/libs/rxjs/utils';
import { JumpTo_2D, TweenToStart } from '../../../../../scripts/libs/rxjs/cc3/TweenStart';
import { nc } from '../../../../../scripts/libs/rxjs/NotificationCenter';
import { v3 } from 'cc';
import { AnimationPlay } from '../../../../../scripts/libs/rxjs/cc3/AnimationPlay';
import { Animation } from 'cc';
const { ccclass, property, executeInEditMode } = _decorator;

@ccclass('PillarView')
@executeInEditMode
export class PillarView extends BaseView {

    posId: number = null;
    pillarId: number = null;

    animatings = ReactiveSet.Create();

    @property(ReactiveNumber)
    _colorId: ReactiveNumber = ReactiveNumber.DefaultValue(0);
    @property
    get colorId(): number { return this._colorId.value }
    set colorId(v: number) { this._colorId.Value = v; }

    @property(ReactiveBoolean)
    _blind: ReactiveBoolean = ReactiveBoolean.DefaultValue(false);
    @property
    get blind(): boolean { return this._blind.value }
    set blind(v: boolean) { this._blind.Value = v; }

    @property(ReactiveBoolean)
    _clickActive: ReactiveBoolean = ReactiveBoolean.DefaultValue(false);
    @property
    get clickActive(): boolean { return this._clickActive.value }
    set clickActive(v: boolean) { this._clickActive.Value = v; }

    @property(ReactiveNumber)
    _expendProgress: ReactiveNumber = ReactiveNumber.DefaultValue(null);
    @property
    get expendProgress(): number { return this._expendProgress.value }
    set expendProgress(v: number) { this._expendProgress.Value = v; }

    @property(ReactiveNumber)
    _waitingProgress: ReactiveNumber = ReactiveNumber.DefaultValue(null);
    @property
    get waitingProgress(): number { return this._waitingProgress.value }
    set waitingProgress(v: number) { this._waitingProgress.Value = v; }

    @property(ReactiveBoolean)
    _isDead: ReactiveBoolean = ReactiveBoolean.DefaultValue(false);
    @property
    get isDead(): boolean { return this._isDead.value }
    set isDead(v: boolean) { this._isDead.Value = v; }

    _targetWaitingProgress: number = null;
    _overWaitingProgress: number = null;

    @property(Node)
    rootNode: Node = null;

    // @property(Sprite)
    // outerSprite: Sprite = null;

    @property([Sprite])
    mainSprites: Sprite[] = [];

    @property(Node)
    shadowNode: Node = null;

    @property(Node)
    unknownNode: Node = null;

    @property(Sprite)
    threeOutlineSprite: Sprite = null;

    // @property(Label)
    // progressLabel: Label = null;

    @property(SpriteAtlas)
    atlas: SpriteAtlas = null;

    useObserves() {
        return [
            MergeASAP(this._colorId, this._blind, this._clickActive, this._waitingProgress, this._isDead).subscribe(this.refresh.bind(this)),
            this._expendProgress.subscribe(this.expendProgressChanged.bind(this)),
            this._blind.subscribePairWise(pair => {
                if (pair[0] != pair[1]) { // 变化
                    nc.post('change_smoke', { worldPos: this.node.worldPosition });
                }
            })
        ];
    }

    reset() {
        this._targetWaitingProgress = 0;
        this._overWaitingProgress = 0;
        this.expendProgress = 0;
        this.animatings.clear();
        this.rootNode.setScale(1, 1, 1);
        this.rootNode.setPosition(0, 0, 0);
        this.clickActive = false;
        nullifySubscription.call(this, '_sub_canclicktip');
        nullifySubscription.call(this, '_sub_bounce');
        nullifySubscription.call(this, '_sub_shake');
        nullifySubscription.call(this, '_sub_expend');
    }

    refresh() {
        let needOuter = this.clickActive;
        if (this.blind) {
            this.threeOutlineSprite.node.active = false;
            this.unknownNode.active = true;
            this.rootNode.active = false;
            this.unknownNode.getComponentsInChildren(Sprite).forEach(_ => {
                _.grayscale = this.isDead;
            });
        } else if (this.clickActive) {
            this.threeOutlineSprite.node.active = true;
            this.unknownNode.active = false;
            this.rootNode.active = true;
            this.threeOutlineSprite.getComponent(Sprite).spriteFrame = this.atlas.getSpriteFrame(`s/s${this.colorId}t`);
            this.threeOutlineSprite.grayscale = this.isDead;
            this.mainSprites.forEach(_ => {
                _.node.active = false;
            });
        } else {
            this.threeOutlineSprite.node.active = false;
            this.unknownNode.active = false;
            this.rootNode.active = true;
            this.mainSprites.forEach(_ => {
                _.node.active = true;
                _.grayscale = this.isDead;
                _.spriteFrame = this.atlas.getSpriteFrame(`s/s${this.colorId}${needOuter ? 'o' : ''}`);
            });
        }

        for (let i = 0; i < 3; i++) {
            if (i < 3 - this.waitingProgress) {
                this.mainSprites[i].node.active = true;
            } else {
                this.mainSprites[i].node.active = false;
            }
        }
        if (this.waitingProgress >= 3) {
            this.shadowNode.getComponent(UIOpacity).opacity = 0;
        } else {
            this.shadowNode.getComponent(UIOpacity).opacity = 255;
        }
    }

    expendProgressChanged() {
        this.mainSprites.forEach((_, idx) => {
            _.node.setPosition(0, this.getSwimringPositionByIdx(idx));
            if (this.expendProgress < .01 && idx > 0) {
                _.node.getComponent(UIOpacity).opacity = 0;
            } else {
                _.node.getComponent(UIOpacity).opacity = 255;
            }
        });
    }

    getSwimringPositionByIdx(idx: number) {
        return 20 * idx * this.expendProgress;
    }

    _sub_expend: Subscription = null;
    expendTo(value) {
        nullifySubscription.call(this, '_sub_expend');
        this._sub_expend = TweenToStart(this, .2, { expendProgress: value }, { easing: 'backOut' }).subscribe();
    }

    _sub_canclicktip: Subscription = null;
    canClickTip() { // 游泳圈的缩放提示
        nullifySubscription.call(this, '_sub_canclicktip');
        this._sub_canclicktip = forkJoin([
            concat(
                TweenToStart(this.rootNode, .1, { position: v3(0, 10, 0) }, { easing: 'sineOut' }),
                TweenToStart(this.rootNode, .1, { position: v3(0, 0, 0) }, { easing: 'sineIn' }),
            ),
            AnimationPlay(this.rootNode.getComponent(Animation), 'block_root_bounce'),
        ]).subscribe();
    }

    _sub_bounce: Subscription = null;
    bounce() {
        nullifySubscription.call(this, '_sub_bounce');
        this._sub_bounce = AnimationPlay(this.rootNode.getComponent(Animation), 'block_root_bounce').subscribe();
    }

    _sub_shake: Subscription = null;
    shake() {
        nullifySubscription.call(this, '_sub_shake');
        this._sub_shake = AnimationPlay(this.rootNode.getComponent(Animation), 'block_root_shake').subscribe();
    }
}

